﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Globalization;
using System.Windows.Data;
using LiveEduWizard.Filter;

namespace LiveEduWizard.Views
{
    public partial class TimetableView : PanoramaItem
    {
        private Rectangle HeaderRectangle = null;

        public TimetableView()
        {            
            InitializeComponent();

            TimetableControl.Range = new Timetable.TimeRange(7, 19);

            WatchOverScrollViewer();
        }

        #region Watching over scrolling
        DependencyProperty VerticalOffsetWatcherProperty = DependencyProperty.Register(
            "VerticalOffsetWatcher", typeof(double), typeof(TimetableView),
            new PropertyMetadata(new PropertyChangedCallback(OnVerticalOffsetWatcherChanged)));

        protected void WatchOverScrollViewer()
        {
            Binding binding = new Binding();
            binding.Source = ScrollViewer;
            binding.Path = new PropertyPath("VerticalOffset");
            binding.Mode = BindingMode.OneWay;
            this.SetBinding(VerticalOffsetWatcherProperty, binding);
        }

        public double VerticalOffsetWatcher
        {
            get { return (double)this.GetValue(VerticalOffsetWatcherProperty); }
            set { this.SetValue(VerticalOffsetWatcherProperty, value); }
        }

        private static void OnVerticalOffsetWatcherChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            TimetableView control = obj as TimetableView;

            if (((Panorama)control.Parent).SelectedItem == control)
            {
                control.scrolling = true;
                control.VerticalOffset = control.ScrollViewer.VerticalOffset;
                control.scrolling = false;
            }
        }
        #endregion
        
        public static readonly DependencyProperty TimetableProperty = DependencyProperty.Register("Timetable", 
            typeof(TimetableViewModel), typeof(TimetableView), new PropertyMetadata(null, new PropertyChangedCallback(OnTimetableChanged)));

        private TimetableViewModel timetable = null;
        public TimetableViewModel Timetable
        {
            get { return (TimetableViewModel)this.GetValue(TimetableProperty); }
            set { SetValue(TimetableProperty, value); }
        }   
     
        private static void OnTimetableChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            TimetableView view = (TimetableView)d;
            if (view.timetable != e.NewValue)
            {
                view.timetable = (TimetableViewModel)e.NewValue;

                view.UpdateTimetable();
            }
        }

        public static readonly DependencyProperty VerticalOffsetProperty = DependencyProperty.Register("VerticalOffset",
            typeof(double), typeof(TimetableView), new PropertyMetadata(0.0, new PropertyChangedCallback(OnVerticalOffsetChanged)));

        public double VerticalOffset
        {
            get { return (double)this.GetValue(VerticalOffsetProperty); }
            set { SetValue(VerticalOffsetProperty, value); }
        }

        private bool scrolling = false;
        private static void OnVerticalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TimetableView view = (TimetableView)d;
            if (!view.scrolling)
            {
                view.ScrollViewer.ScrollToVerticalOffset((double)e.NewValue);
            }
        }

        public static readonly DependencyProperty FilterProperty = DependencyProperty.Register("Filter",
            typeof(IFilterRule), typeof(TimetableView), new PropertyMetadata(null, new PropertyChangedCallback(OnFilterChanged)));

        public IFilterRule Filter
        {
            get { return (IFilterRule)this.GetValue(FilterProperty); }
            set { SetValue(FilterProperty, value); }
        }

        private static void OnFilterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((TimetableView)d).TimetableControl.ApplyFilter((IFilterRule)e.NewValue);
        }

        private DayOfWeek dayOfWeek;
        public DayOfWeek DayOfWeek
        {
            get 
            { 
                return dayOfWeek;
            }
            set
            {
                dayOfWeek = value;
                Header = CultureInfo.CurrentCulture.DateTimeFormat.DayNames[(int)dayOfWeek].ToLower();

                UpdateTimetable();
            }
        }

        private void UpdateTimetable()
        {
            TimetableControl.Items = null;

            if (timetable != null)
            {
                switch (dayOfWeek)
                {
                    case System.DayOfWeek.Monday:
                        TimetableControl.Items = timetable.Monday;
                        break;
                    case System.DayOfWeek.Tuesday:
                        TimetableControl.Items = timetable.Tuesday;
                        break;
                    case System.DayOfWeek.Wednesday:
                        TimetableControl.Items = timetable.Wednesday;
                        break;
                    case System.DayOfWeek.Thursday:
                        TimetableControl.Items = timetable.Thursday;
                        break;
                    case System.DayOfWeek.Friday:
                        TimetableControl.Items = timetable.Friday;
                        break;
                }
            }
        }

        private void HeaderRectangle_Loaded(object sender, RoutedEventArgs e)
        {
            HeaderRectangle = sender as Rectangle;

            UpdateHeader();
        }

        private void UpdateHeader()
        {
            if (TimetableControl != null)
                HeaderRectangle.Visibility = TimetableControl.HasVisibleItem ? Visibility.Visible : Visibility.Collapsed;
        }

        private void TimetableControl_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
                case "HasVisibleItem":
                    UpdateHeader();
                    break;
            }
        }
    }
}
